package com.liy.teaching.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.liy.teaching.entity.ProductEntity;
import com.liy.teaching.mapper.ProductMapper;
import com.liy.teaching.service.ProductService;
import com.liy.teaching.util.JSONUtil;
import org.redisson.api.RBloomFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.Serializable;
import java.util.Random;
import java.util.concurrent.TimeUnit;

/**
 * 布隆过滤器判断 不存在  准确率100%
 * 可以判断某样东西一定不存在
 *
 * 商品服务
 **/
@Service
public class ProductServiceImpl extends ServiceImpl<ProductMapper, ProductEntity> implements ProductService {

    //前缀
    private static final String KEY_PREFIX = "product:";

    //  格式化一下
    private static String buildKey(String id) {
        return KEY_PREFIX + id;  // product:商品ID
    }



    @Resource(name = "redisTemplate")
    private ValueOperations<Serializable, String> redisOperations;


    @Autowired
    private RBloomFilter<String> redisBloomFilter;


    /**
     * 重载 getById(id)  做第一点增强
     *
     */
    @Override
    public ProductEntity getById(Serializable id) {

        String redisKey = buildKey(String.valueOf(id)); // 构建rediskey

        if(!redisBloomFilter.contains(redisKey)){  // 布隆过滤器判断 redisKey 不存在
            return null;
        }

        String redisValue = redisOperations.get(redisKey);  // 从缓存中去查

        if (redisValue != null) {  // 查到了

            return JSONUtil.parseObject(redisValue, ProductEntity.class); //直接返回;

        } else { // 没查到
            ProductEntity product = getBaseMapper().selectById(id); // 从数据库中查, 然后放到缓存中;
            if(product !=null){

                String jsonString = JSONUtil.toJSONString(product);

                long radomLong = radomLong();  // 随机产生一个数 ( 24 ~ 72 )

                redisOperations.set(redisKey, jsonString, radomLong, TimeUnit.HOURS);    // 放到缓存中, 时间取随机, 时间单位小时

                return product;
            }

            return null;
        }


    }


    public static long radomLong(){
        long min = 24;
        long max = 72;
        long rangeLong = min + (((long) (new Random().nextDouble() * (max - min))));
        return rangeLong;
    }

}
